﻿/*
 * (c) Stefan Bojarovski 2010
 * */
using System;
using System.IO;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ASTBuilder
{
    class ExpressionNode : NodesCollection, IArithmeticNode
    {
        private LexemeType lexType = LexemeType.EXPRESSSION;
        private TokenType expressionType;
        private IArithmeticNode firstOperand;
        private IArithmeticNode secondOperand;
        private bool UMinus;

        public ExpressionNode(TokenType someTType, IArithmeticNode fOperand, IArithmeticNode sOperand)
        {
            expressionType = someTType;
            firstOperand = fOperand;
            secondOperand = sOperand;
        }
        public LexemeType getLexemeType()
        {
            return lexType;
        }
        public void setNegative()
        {
            UMinus = true;
            firstOperand.setNegative();
        }
        public IArithmeticNode getFirst()
        {
            return firstOperand;
        }
        public IArithmeticNode getSecond()
        {
            return secondOperand;
        }
        public void printNode(String parentLevel, StreamWriter someStream)
        {
            someStream.WriteLine(parentLevel + " " + "Expression: ");
            someStream.WriteLine(parentLevel + " " + "FirstOperand: ");
            firstOperand.printNode(parentLevel + " ", someStream);
            if (expressionType != TokenType.UNKNOWN)
            {
                someStream.WriteLine(parentLevel + " " + expressionType.ToString());
            }
            if (secondOperand != null)
            {
                someStream.WriteLine(parentLevel + " " + "SecondOperand: ");
                secondOperand.printNode(parentLevel + " ", someStream);
            }
        }
        public List<Command> evalNode(ref Direction next, 
                                        ref Dictionary<String, Pair<IdentifierType, object>> Environment)
        {
            Command first = firstOperand.evalNode(ref next, ref Environment)[0];
            Command second;
            Command result;
            if (secondOperand != null)
            {
                second = secondOperand.evalNode(ref next, ref Environment)[0];
                object Value = null;

                switch (expressionType)
                {
                    case TokenType.PLUS:
                    case TokenType.INC:
                        Value = (int)first.getIdValue() + (int)second.getIdValue();
                        break;
                    case TokenType.MINUS:
                    case TokenType.DEC:
                        Value = (int)first.getIdValue() - (int)second.getIdValue();
                        break;
                }
                result = new Command(CommandType.EVALUABLE, null, Value);
            }
            else
            {
                result = new Command(CommandType.EVALUABLE, first.getIdName(), first.getIdValue());
            }
            List<Command> exprResult = new List<Command>();
            exprResult.Add(result);
            return exprResult;
        }
    }
}
